//
//  main.cpp
//  AirLogClientCMD
//
//  Created by Penghao on 14-1-8.
//  Copyright (c) 2014年 PengHao.
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//

#include <iostream>
#include <time.h>
#include <string.h>
#include "AirData.h"
#include "AirLog.h"
#include "AirHttpConnect.h"
#include "AirMath.h"
#include "AirLinearRegression.h"
#include "AirMotion.h"
#include "AirObjectRef.h"
#include "AirThread.h"
#include "AirLinuxThread.h"
#include "AirSocketConnect.h"
#include "AirSocketServer.h"
#include "AirSocketLog.h"
#include "AirSocketModel.h"
//#include "Msg.pb.h"
extern int test();

class AirLinerDeterminant4 : public AirCpp::AirMath::LinearAlgebra::AirDeterminant4 {
public:
    float get_X(float x){
        return x;
    }
};

#define TEST 100
using namespace AirCpp;
using namespace AirMath;
using namespace LinearAlgebra;
static AirLinearRegression<AirDeterminant3> *p_leastSquare3 = new AirLinearRegression<AirDeterminant3>();

static float d0 = 1.0;


AirPoint3 phrase_point(float d, float p){
    float x = log10(d/d0);
    float y = p;
    return AirPoint3(1.0, x, y);
}

//class TestModle : AirModel {
//private:
//    AirInt32 rssi;
//    double distance;
//    AirString *beacon_id;
//    
//public:
//    
//    virtual AirDataStreamBuffer *stream_buffer(){
//        AirDataStreamBuffer *buffer = AirDataStreamBuffer::create_instream_buffer(total_length);
//        buffer->append_data(rssi);
//        buffer->append_data(distance);
//        buffer->append_data(beacon_id->length);
//        buffer->append_c_data(beacon_id->c_str, beacon_id->length);
//        return buffer;
//    }
//    
//    virtual bool prase(AirDataStreamBuffer *stream_buffer){
//        stream_buffer->read_data(rssi);
//        stream_buffer->read_data(distance);
//        AirSize_t str_len = 0;
//        stream_buffer->read_data(str_len);
//        beacon_id = new AirString();
//        beacon_id->init(str_len);
//        stream_buffer->read_c_data(beacon_id->c_str, str_len);
//        return true;
//    }
//    
//    void set_rssi(AirInt32 rssi_){
//        rssi = rssi_;
//        total_length+= sizeof(AirInt32);
//    }
//    
//    void set_distance(double distance_){
//        distance = distance_;
//        total_length += sizeof(double);
//    }
//    
//    void set_beacon_id(AirString *beacon_id_){
//        beacon_id = retain(beacon_id_);
//    }
//};

class AirHttpTEST {
public:
    
    void recevied_finished(AirHttpConnect<AirHttpTEST> *connect, const void *context){
        AirString *data = connect->http_response->response_data;
        printf("\n ====http head==== \n");
        connect->http_response->response_header.decs();
        printf("\n ====http boddy==== \n");
        printf("%s", data->c_str);
    }
    
};

int http_test(){
    
    AirHttpTEST test;
    AirString *host = new AirString("http://localhost/api.php");
    AirString *method = new AirString("POST");
    AirString *version = new AirString(AirHttpVersion1_1);
    AirString * connection_key = new AirString("Connection");
    AirString * connection_val = new AirString("Keep-Alive");
    AirString * cache_key = new AirString("Cache-Control");
    AirString * content_type = new AirString("Content-Type");
    AirString * cache_val = new AirString("no-cache");
    AirString * content_type_val = new AirString("text/html");
    
    AirHttpConnect<AirHttpTEST> *httpConn = new AirHttpConnect<AirHttpTEST>();
    httpConn->init(host, method, version, NULL);
    httpConn->set_head_feild(connection_key, connection_val);
    httpConn->set_head_feild(cache_key, cache_val);
    httpConn->set_head_feild(content_type, content_type_val);
    
    AirData data;
    AirString *body = new AirString("{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}\r\n");
    data.init(body->c_str, body->length);
    httpConn->set_body(&data);
    httpConn->set_callback(&test);
    httpConn->connect();
    
    release(host);
    release(method);
    release(version);
    release(connection_key);
    release(connection_val);
    release(cache_key);
    release(cache_val);
    
    return 0;
}

#define CONN_NUM 1
static EnableSocketLog logconnect[CONN_NUM];

int test_log_server(int port){
    AirString * url = new AirString("127.0.0.1");
    for (int j = 0; j < CONN_NUM; ++j) {
        logconnect[j].init(url, port);
        usleep(1000);
    }
    for (int i = 0; i <1000; ++i) {
        AirInt32 rssi = i+1;
        double distance = 2.0*rssi+1.0;
        char beacon_id[100];
        sprintf(beacon_id, "air_beacon_id_%d", i%2);

        TestModle modle;
        modle.set_rssi(rssi);
        modle.set_distance(distance);
        AirString str(beacon_id);
        modle.set_beacon_id(&str);
        AirDataStreamBuffer *buffer = modle.stream_buffer();
        
        TestModle modle1;
        modle1.prase(buffer);
        
        for (int j = 0; j < CONN_NUM; ++j) {
            logconnect[j].log(buffer);
            usleep(10000);
        }
    }
    return 0;
}

int test_math(){
    
    retain(p_leastSquare3);
    p_leastSquare3->init();
    for (int i = 0; i < 1000; ++i) {
        float x = rand()%100/100.0;
        float y = powf(3, x);
        p_leastSquare3->add_point(phrase_point(x, y));
    }
    AirPoint3 *rs = NULL;
    double average_y;
    p_leastSquare3->linear_equations(average_y, rs);
    rs->desc();
    return 0;
}


class AirTEST {
public:
    
    void *connect(void *){
        test_log_server(8890);
        return NULL;
    }
    
public:
    void start_reseive_with_muilthread(){
        AirThread<AirTEST> * reseive_thread;
        AirOperation<AirTEST> *operation = new AirOperation<AirTEST>();
        operation->init(this, &AirTEST::connect, NULL);
        reseive_thread = new AirThread<AirTEST>();
        reseive_thread->init();
        reseive_thread->run_operation(operation);
        release(operation);
    }
};

int main(int argc, const char * argv[])
{
    http_test();
    return 0;
    
    int port = 8890;
    int threadnum = 1;
    if (argc == 2) {
        threadnum = atoi(argv[1]);
        printf("threadnum = %d \n", port);
    }
    
    
    
    
    AirTEST test;
    for (int i = 0; i < threadnum; ++i) {
        test.start_reseive_with_muilthread();
        usleep(10000);
    }
    sleep(100);
    return 0;
    
    test_log_server(8890);
    return 0;
    for (int i = 0; i < 2; ++i) {
        switch (fork()) {
            case -1:
                exit(-1);
                break;
                
            case 0:
                test_log_server(8890);
                break;
                
            default:
                sleep(1);
                continue;
        }
    }
    return 0;
    
};